use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};

use crate::HashMap;

#[derive(Serialize, Deserialize, Debug, PartialEq, Builder)]
#[builder(name = "MessageConstructor")]
pub struct Message {
    pub from: String,
    pub to_cap: String,
    pub text: String,
    pub freq: u32,
}

const SPACE: u32 = 0x20;
const LEFT_BRACKET: u32 = 0x5b;
const QUESTION_MARK: u32 = 0x3f;

lazy_static! {
    static ref LETTERS: HashMap<char, u32> = {
        HashMap::from([
            ('А', 0x41),
            ('В', 0x42),
            ('Ё', 0x65),
            ('М', 0x4d),
            ('Н', 0x48),
            ('О', 0x4f),
            ('Р', 0x50),
            ('Т', 0x54),
            ('Х', 0x58),
            (']', 0x5d),
            ('\'', 0x60),
            ('Б', 0x61),
            ('Г', 0x62),
            ('Д', 0x64),
            ('Е', 0x45),
            ('Ж', 0x66),
            ('З', 0x67),
            ('И', 0x68),
            ('Й', 0x69),
            ('Л', 0x6a),
            ('П', 0x6b),
            ('У', 0x6c),
            ('Ф', 0x6d),
            ('Ц', 0x6e),
            ('Ч', 0x6f),
            ('Ш', 0x70),
            ('Щ', 0x71),
            ('Ъ', 0x72),
            ('Ы', 0x73),
            ('Ь', 0x74),
            ('Э', 0x75),
            ('Ю', 0x76),
            ('Я', 0x77),
            ('С', 0x43),
            ('К', 0x4b),
            ('~', 0x7e),
        ])
    };
}
impl Message {
    pub fn msg_to_send(&self) -> String {
        let d: String = vec![self.text.trim(), " ", self.from.trim()]
            .concat()
            .to_uppercase();
        let after: String = d
            .chars()
            .map(|c| {
                if SPACE <= c as u32 && c as u32 <= LEFT_BRACKET {
                    c
                } else {
                    char::from_u32(*LETTERS.get(&c).unwrap_or(&QUESTION_MARK)).unwrap_or('?')
                }
            })
            .collect();
        vec![
            "\"".to_string(),
            self.to_cap.clone(),
            ":".to_string(),
            after,
            "\"".to_string(),
        ]
        .join("")
    }
}
